﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Services;
using System.Web.UI;
using LiveWebService.ELMS;
using LiveWebService.EWSModule;
using LiveWebService.IUV;
using LiveWebService.ManageDomain;
using LiveWebService.PSW;
using LiveWebService.SSO;
using LiveWebServiceBase;
using LiveWebServiceBase.AOPLogWriter;
using LiveWebServiceBase.ReturnedTypes;
using LiveWebServiceBase.ServiceUser;
using Microsoft.Exchange.WebServices.Data;

namespace LiveWebService
{
    /// <summary>
    /// This web service is includes methods for work with Live technology.
    /// 1. PowerShellWrapper 
    /// 2. Exchange Web Service
    /// 3. Windows Live Admin Center
    /// 4. LiveSLT
    /// 5. MSDN AA ELMS
    /// 6. MSDN AA IUV
    /// </summary>
    [LogWriterAspect]
    [WebService(Namespace = "http://efms.ws")]
    [WebServiceBinding(ConformsTo = WsiProfiles.None)]
    [System.ComponentModel.ToolboxItem(true)]
    //[XmlInclude(typeof(ContactParameterClass))]
    //[XmlInclude(typeof(LiveWebServiceBase.ReturnedTypes.PhysicalAddressEntry))]
    //[XmlInclude(typeof(LiveWebServiceBase.ReturnedTypes.EmailAddressEntry))]
    //[XmlInclude(typeof(LiveWebServiceBase.ReturnedTypes.Contact))]
    public class efms : System.Web.Services.WebService
    {
        private User suCurrentUser;

        public efms()
        {
            suCurrentUser = new User(this.Context.User.Identity.Name);
        }

        #region ELMS

        #region GetRedirectURL
        /// <summary>
        /// Get Url of MSDN AA service with included authorization for WindowsLiveID
        /// </summary>
        /// <param name="LiveID">User Windows Live ID</param>
        /// <returns>Url to MSDN AA service</returns>
        [WebMethod(Description = "Get Url of MSDN AA service with included authorization for WindowsLiveID.",
            MessageName = "ELMS_GetRedirectURL1")]
        public string ELMS_GetUrl(string LiveID)
        {
            return ELMS_GetUrl(LiveID, null, null, null, null);
        }

        /// <summary>
        /// Get Url of MSDN AA service with included authorization for WindowsLiveID
        /// </summary>
        /// <param name="LiveID">User Windows Live ID</param>
        /// <param name="GroupName">Name of MSDN AA security group</param>
        /// <param name="firstName">User's first name, which shows on MSDN AA page</param>
        /// <param name="lastName">User's last name, which shows on MSDN AA page</param>
        /// <param name="email">User's email address, which shows on MSDN AA page</param>
        /// <returns>Url to MSDN AA service</returns>
        [WebMethod(Description = "Get Url of MSDN AA service with included authorization for WindowsLiveID.",
            MessageName = "ELMS_GetRedirectURL2")]
        public string ELMS_GetUrl(string LiveID, String GroupName, String firstName, String lastName, String email)
        {
            string domainName = LiveID.Split('@')[1];

            LiveELMS clELMS = new LiveELMS(suCurrentUser, LiveID);
            return clELMS.GetELMSRedirectString(GroupName, firstName, lastName, email);
        }
        #endregion

        #endregion

        #region IUV
        /// <summary>
        /// Get Url of MSDN AA service with included authorization for WindowsLiveID
        /// </summary>
        /// <param name="LiveID">User Windows Live ID</param>
        /// <returns>Url to MSDN AA service</returns>
        [WebMethod(Description = "Get Url of MSDN AA service with included authorization for WindowsLiveID.",
            MessageName = "IUV_GetUrl1")]
        public string IUV_GetUrl(string LiveID)
        {
            return IUV_GetUrl(LiveID, null, null, null, null, null);
        }

        /// <summary>
        /// Get Url of MSDN AA service with included authorization for WindowsLiveID
        /// </summary>
        /// <param name="LiveID">User Windows Live ID</param>
        /// <param name="email">User's email address, which shows on MSDN AA page</param>
        /// <param name="shopperIP">User's client IP address</param>
        /// <param name="firstName">User's first name, which shows on MSDN AA page</param>
        /// <param name="lastName">User's last name, which shows on MSDN AA page</param>
        /// <param name="academicStatuses">Name of MSDN AA security group</param>
        /// <param name="webstoreName">Name of MSDN AA webstore name</param>
        /// <returns>Url to MSDN AA service</returns>
        [WebMethod(Description = "Get Url of MSDN AA service with included authorization for WindowsLiveID.",
            MessageName = "IUV_GetUrl2")]
        public string IUV_GetUrl(string LiveID, String shopperIP, String firstName, String lastName, String academicStatuses, String webstoreName)
        {
            LiveIUV clIUV = new LiveIUV(suCurrentUser, LiveID);
            return clIUV.GetIUVRedirectString(LiveID, shopperIP, firstName, lastName, academicStatuses, webstoreName);
        }

        #endregion

        #region LiveSLT

        #region GetURL
        /// <summary>
        /// Get Url and service type dictionary
        /// </summary>
        /// <returns>Array of pair object where first is service name and second is service url</returns>
        [WebMethod(Description = "Get Url and service type dictionary.", MessageName = "SSO_GetRawUrl1")]
        public List<Pair> SSO_GetRawUrl()
        {
            List<Pair> lstPairs = new List<Pair>();

            foreach (var item in Settings.LiveEduServiceURLs.redirectTypeDictionary)
                lstPairs.Add(new Pair(item.Key, item.Value));

            return lstPairs;
        }

        /// <summary>
        /// "Get Url by service type
        /// </summary>
        /// <param name="redirectType">One of RedirectType enum or string name of service</param>
        /// <returns></returns>
        [WebMethod(Description = "Get Url by service type.", MessageName = "SSO_GetRawUrl2")]
        public string SSO_GetRawUrl(RedirectType redirectType)
        {
            if (Settings.LiveEduServiceURLs.redirectTypeDictionary.Count(le => le.Key == redirectType) == 1)
                return Settings.LiveEduServiceURLs.redirectTypeDictionary.Single(le => le.Key == redirectType).Value;
            else
                throw new Exception("Can't find service with specified redirect type.");
        }

        [WebMethod(Description = "Get Url by service name.", MessageName = "SSO_GetRawUrl3")]
        public string SSO_GetRawUrl(string serviceName)
        {
            if (Settings.LiveEduServiceURLs.redirectTypeDictionary.Count(le => le.Key.ToString().ToLower() == serviceName.ToLower()) == 1)
                return Settings.LiveEduServiceURLs.redirectTypeDictionary.Single(le => le.Key.ToString().ToLower() == serviceName.ToLower()).Value;
            else
                throw new Exception("Can't find service with specified service name.");
        }

        [WebMethod(Description = "Get Url of service with included SLT for WindowsLiveID.", MessageName = "SSO_GetUrl1")]
        public string SSO_GetUrl(string LiveID, string serviceUrl)
        {
            string RedirectUrl = string.Empty;

            if (!serviceUrl.ToLower().Contains("http://") && !serviceUrl.ToLower().Contains("https://"))
            {
                if (Settings.LiveEduServiceURLs.redirectTypeDictionary.Count(le => le.Key.ToString().ToLower() == serviceUrl.ToLower()) == 0)
                    throw new Exception("Unable to find service with this name: " + serviceUrl);
                else
                    RedirectUrl = HttpUtility.UrlEncode(Settings.LiveEduServiceURLs.redirectTypeDictionary.Single(le => le.Key.ToString().ToLower() == serviceUrl.ToLower()).Value);
            }
            else
                RedirectUrl = HttpUtility.UrlEncode(serviceUrl);

            LiveSLT clSLT = new LiveSLT(suCurrentUser, LiveID);

            string stSLT = clSLT.GetSLT();
            return clSLT.CreateRedirectString(stSLT, RedirectUrl);
        }

        [WebMethod(Description = "Get Url of service with included SLT for WindowsLiveID.", MessageName = "SSO_GetUrl2")]
        public string SSO_GetUrl(string LiveID, RedirectType redirectType)
        {
            string RedirectUrl = string.Empty;

            if (Settings.LiveEduServiceURLs.redirectTypeDictionary.Count(le => le.Key == redirectType) == 1)
                RedirectUrl = Settings.LiveEduServiceURLs.redirectTypeDictionary.Single(le => le.Key == redirectType).Value;
            else 
                throw new Exception("Can't find service with specified redirect type.");

            LiveSLT clSLT = new LiveSLT(suCurrentUser, LiveID);

            string stSLT = clSLT.GetSLT();
            return clSLT.CreateRedirectString(stSLT, RedirectUrl);
        }

        [WebMethod(Description = "Get Url of services with included SLT for WindowsLiveID.", MessageName = "SSO_GetUrl3")]
        public List<LiveRedirectURL> SSO_GetUrl(string LiveID)
        {
            List<LiveRedirectURL> lstUrl = new List<LiveRedirectURL> { };

            LiveSLT clSLT = new LiveSLT(suCurrentUser, LiveID);


            foreach (var item in Settings.LiveEduServiceURLs.redirectTypeDictionary)
                lstUrl.Add(new LiveRedirectURL() { urlType = item.Key, url = clSLT.CreateRedirectString(clSLT.GetSLT(), item.Value) });

            return lstUrl;
        }

        [WebMethod(Description = "Get Url of Outlook with included SLT for Microsoft Online Services ID..")]
        public string SSO_GetURLFromSsoProxy(string LiveID, string serviceUrl)
        {
            LiveSLT clSLT = new LiveSLT(suCurrentUser, LiveID);

            return clSLT.CreateRedirectStringO365(serviceUrl);
        }

        #endregion

        #region GetSLT
        [WebMethod(Description = "Get RAW SLT for WindowsLiveID.")]
        public string SSO_GetSLT(string LiveID)
        {
            LiveSLT clSLT = new LiveSLT(suCurrentUser, LiveID);

            return clSLT.GetSLT();
        }

        [WebMethod(Description = "Get RAW SLT for Microsoft Online Services ID.")]
        public string SSO_GetSLTFromSsoProxy(string LiveID)
        {
            LiveSLT clSLT = new LiveSLT(suCurrentUser, LiveID);

            return clSLT.GetSltFromSsoProxy();
        }

        #endregion

        #endregion

        #region ManageDomain2

        #region Set member subscription
        [WebMethod(Description = "Provisions a subscription on Windows Live ID. ManageDomains2 will be deprecated in march. Use PS_Mailbox_Create instead.", MessageName = "MD2_Offer_Set1")]
        public void MD2_Offer_Set(string LiveID, string offerName)
        {
            ManageDomain2 manageDomain2 = new ManageDomain2(suCurrentUser, LiveID);
            manageDomain2.ProvisionMemberSubscription(LiveID, offerName);
        }
        #endregion

        #region Remove member subscription
        [WebMethod(Description = "Provisions a subscription on Windows Live ID. ManageDomains2 will be deprecated in march. Use PS_Mailbox_Create instead.", MessageName = "MD2_Offer_Remove1")]
        public void MD2_Offer_Remove(string LiveID, string offerName)
        {
            ManageDomain2 manageDomain2 = new ManageDomain2(suCurrentUser, LiveID);
            manageDomain2.DeprovisionMemberSubscription(LiveID, offerName);
        }
        #endregion

        #region Create new Live ID
        [WebMethod(Description = "Create Windows Live ID. ManageDomains2 will be deprecated in march. Use PS_Mailbox_Create instead.", MessageName = "MD2_Create1")]
        public LiveUser MD2_Create(LiveUser newUser)
        {
            ManageDomain2 manageDomain2 = new ManageDomain2(suCurrentUser, newUser.username);

            MemberNameState memberNameState = manageDomain2.GetMemberNameState(newUser.username);
            if (memberNameState == MemberNameState.Available)
            {
                manageDomain2.CreateMember(newUser.username, newUser.password, newUser.resetpassword,
                    newUser.firstname, newUser.lastname, newUser.lcid);

                newUser.userstatus = LiveUserStatus.Created;
            }
            else
            {
                newUser.userstatus = LiveUserStatus.InUse;
            }

            return newUser;
        }

        [WebMethod(Description = "Create Windows Live IDs. ManageDomains2 will be deprecated in march. Use PS_Mailbox_Create instead.", MessageName = "MD2_Create2")]
        public List<LiveUser> MD2_Create(List<LiveUser> lstNewUsers)
        {
            string domainName = string.Empty;

            for (int i = 0; i < lstNewUsers.Count - 1; i++)
            {
                LiveUser user = lstNewUsers[i];
                user.userstatus = LiveUserStatus.Error;
                lstNewUsers[i] = user;

                if (domainName == string.Empty)
                    domainName = user.username.Split('@')[1];
                else if (domainName != user.username.Split('@')[1])
                    throw new Exception("All users must belong to this domain: " + domainName + ". Error on item: " + i);
            }

            if (lstNewUsers.Count > 20)
            {
                return lstNewUsers;
            }

            ManageDomain2 manageDomain2 = new ManageDomain2(suCurrentUser, lstNewUsers.FirstOrDefault().username);

            for (int i = 0; i < lstNewUsers.Count - 1; i++)
            {
                LiveUser user = lstNewUsers[i];

                MemberNameState memberNameState = manageDomain2.GetMemberNameState(user.username);
                if (memberNameState == MemberNameState.Available)
                {
                    manageDomain2.CreateMember(user.username, user.password, user.resetpassword,
                        user.firstname, user.lastname, user.lcid);

                    user.userstatus = LiveUserStatus.Created;
                }
                else
                {
                    user.userstatus = LiveUserStatus.InUse;
                }
            }

            return lstNewUsers;
        }
        #endregion

        #region Change Live ID password
        [WebMethod(Description = "Reset password for Windows Live ID. ManageDomains2 will be deprecated in March, 2010. Use PS_Mailbox_ChangePassword instead.")]
        public void MD2_ChangePassword(string LiveID, string newPassword, bool resetPassword)
        {
            ManageDomain2 manageDomain2 = new ManageDomain2(suCurrentUser, LiveID);

            manageDomain2.ResetMemberPassword(LiveID, newPassword, resetPassword);
        }
        #endregion

        #region Rename Live ID
        [WebMethod(Description = "Rename Windows Live ID. ManageDomains2 will be deprecated in March, 2010. Use PS_Mailbox_Rename instead.")]
        public void MD2_Rename(string LiveID, string newLiveID)
        {
            ManageDomain2 manageDomain2 = new ManageDomain2(suCurrentUser, LiveID);
            manageDomain2.RenameMember(LiveID, newLiveID);
        }
        #endregion

        #region Delete Live ID
        [WebMethod(Description = "Delete Windows Live ID. ManageDomains2 will be deprecated in March, 2010. Use PS_Mailbox_Delete instead.")]
        public void MD2_Delete(string LiveID)
        {
            ManageDomain2 manageDomain2 = new ManageDomain2(suCurrentUser, LiveID);
            manageDomain2.DeleteMember(LiveID);
        }
        #endregion

        #region Enumerate Live Domains
        [WebMethod(Description = "Enumerate Live domains. ManageDomains2 will be deprecated in March, 2010.", MessageName = "MD2_EnumDomains1")]
        public DomainInfo[] MD2_EnumDomains()
        {
            return MD2_EnumDomains(null);
        }

        [WebMethod(Description = "Enumerate Live domains. ManageDomains2 will be deprecated in March, 2010.", MessageName = "MD2_EnumDomains2")]
        public DomainInfo[] MD2_EnumDomains(String domain)
        {
            if (domain == null)
            {
                List<string> domains = suCurrentUser.GetDomains();

                if (domains.Count == 1)
                    domain = domains[0];
                else
                {
                    throw new Exception("You have more than one domain. You should set domain property.");
                }
            }

            ManageDomain2 manageDomain2 = new ManageDomain2(suCurrentUser, "admin@" + domain);

            return manageDomain2.EnumDomains();
        }
        #endregion

        #region Enumerate Live Domain Members
        [WebMethod(Description = "Enumerate Live Domain Members. ManageDomains2 will be deprecated in March, 2010.", MessageName = "MD2_EnumMembers1")]
        public string[] MD2_EnumMembers(string start, int memberCount)
        {
            return MD2_EnumMembers(null, start, memberCount);
        }

        [WebMethod(Description = "Enumerate Live Domain Members. ManageDomains2 will be deprecated in March, 2010.", MessageName = "MD2_EnumMembers2")]
        public string[] MD2_EnumMembers(String domain, string start, int memberCount)
        {
            if (domain == null)
            {
                List<string> domains = suCurrentUser.GetDomains();

                if (domains.Count == 1)
                    domain = domains[0];
                else
                {
                    throw new Exception("You have more than one domain. You should set domain property.");
                }
            }

            ManageDomain2 manageDomain2 = new ManageDomain2(suCurrentUser, "admin@" + domain);

            //int memberCount = manageDomain2.GetMemberCount(domain);

            return manageDomain2.EnumMembers(domain, start, memberCount);
        }
        #endregion

        #region Count Live Domain members
        [WebMethod(Description = "Count Live Domain Members. ManageDomains2 will be deprecated in March, 2010.", MessageName = "MD2_CountMembers1")]
        public int MD2_CountMembers()
        {
            return MD2_CountMembers(null);
        }

        [WebMethod(Description = "Count Live Domain Members. ManageDomains2 will be deprecated in March, 2010.", MessageName = "MD2_CountMembers2")]
        public int MD2_CountMembers(String domain)
        {
            if (domain == null)
            {
                List<string> domains = suCurrentUser.GetDomains();

                if (domains.Count == 1)
                    domain = domains[0];
                else
                {
                    throw new Exception("You have more than one domain. You should set domain property.");
                }
            }

            ManageDomain2 manageDomain2 = new ManageDomain2(suCurrentUser, "admin@" + domain);
            return manageDomain2.GetMemberCount(domain);
        }
        #endregion

        #region Get Live ID state
        [WebMethod(Description = "Get state of Windows Live ID. ManageDomains2 will be deprecated in March, 2010. Use PS_Mailbox_GetState instead.")]
        public LiveUserStatus MD2_GetState(string LiveID)
        {
            ManageDomain2 manageDomain2 = new ManageDomain2(suCurrentUser, LiveID);
            {
                MemberNameState state = manageDomain2.GetMemberNameState(LiveID);

                switch (state)
                {
                    case MemberNameState.Available:
                        return LiveUserStatus.Available;
                    case MemberNameState.Blocked:
                        return LiveUserStatus.Blocked;
                    case MemberNameState.InUse:
                        return LiveUserStatus.InUse;
                    case MemberNameState.HMRecyle:
                        return LiveUserStatus.HMRecyle;
                    case MemberNameState.InUseUnmanaged:
                        return LiveUserStatus.InUseUnmanaged;
                    default:
                        return LiveUserStatus.Error;
                }
            }
        }
        #endregion

        #endregion

        #region EWS

        #region Get Emails count
        [WebMethod(Description = "Get Unread and Total Email count for Single Mailbox.", MessageName = "EWS_Email_GetCount1")]
        public MailboxInfo EWS_Email_GetCount(string LiveID)
        {
            LiveEWS clEWS = new LiveEWS(suCurrentUser, LiveID);

            KeyValuePair<int, int> value = clEWS.GetLettersCount(LiveID);

            return new MailboxInfo() { email = LiveID, all = value.Key, unread = value.Value };
        }

        [WebMethod(Description = "Get Unread and Total Email count for Single Mailbox.", MessageName = "EWS_Email_GetCount2")]
        public MailboxInfo EWS_Email_GetCount(string LiveID, string folderName)
        {
            LiveEWS clEWS = new LiveEWS(suCurrentUser, LiveID);

            KeyValuePair<int, int> value = clEWS.GetLettersCount(LiveID, new List<string> { folderName });

            return new MailboxInfo() { email = LiveID, all = value.Key, unread = value.Value };
        }

        [WebMethod(Description = "Get Unread and Total Email count for Single Mailbox.", MessageName = "EWS_Email_GetCount3")]
        public MailboxInfo EWS_Email_GetCount(string LiveID, List<string> foldersNames)
        {
            LiveEWS clEWS = new LiveEWS(suCurrentUser, LiveID);

            KeyValuePair<int, int> value = clEWS.GetLettersCount(LiveID, foldersNames);

            return new MailboxInfo() { email = LiveID, all = value.Key, unread = value.Value };
        }

        [WebMethod(Description = "Get Unread and Total Email count for Bulk Mailboxes.", MessageName = "EWS_Email_GetCount4")]
        public List<MailboxInfo> EWS_Email_GetCount(List<string> lstLiveIDs)
        {
            if (lstLiveIDs.Distinct().Count() > 1)
            {
                throw new Exception("All users must belong to the same domain");
            }

            LiveEWS clEWS = new LiveEWS(suCurrentUser, lstLiveIDs.FirstOrDefault());
            return clEWS.GetLettersCount(lstLiveIDs);
        }
        #endregion

        #region Get Emails
        [WebMethod(Description = "Get Single Email using Mail ID.", MessageName = "EWS_Email_Get1")]
        public LiveWebServiceBase.ReturnedTypes.MailMessage EWS_Email_Get(string LiveID, string MailID, bool IsGetAttachments = false)
        {
            LiveEWS clEWS = new LiveEWS(suCurrentUser, LiveID);
            return clEWS.GetMailMessage(LiveID, MailID, IsGetAttachments);
        }

        [WebMethod(Description = "Get Bulk Emails using Mail IDs.", MessageName = "EWS_Email_Get2")]
        public List<LiveWebServiceBase.ReturnedTypes.MailMessage> EWS_Email_Get(string LiveID, List<string> MailIDs, bool IsGetAttachments = false)
        {
            LiveEWS clEWS = new LiveEWS(suCurrentUser, LiveID);
            List<LiveWebServiceBase.ReturnedTypes.MailMessage> result = new List<LiveWebServiceBase.ReturnedTypes.MailMessage> { };

            foreach (string item in MailIDs)
            {
                result.Add(clEWS.GetMailMessage(LiveID, item, IsGetAttachments));
            }

            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dictionary">Key is LiveID and Value is MailID.</param>
        /// <returns></returns>
        //[WebMethod(Description = "Get Single Email using Mail ID.", MessageName = "EWS_Email_Get3")]
        //public List<LiveWebServiceBase.ReturnedTypes.MailMessage> EWS_Email_Get(Dictionary<string, string> dictionary)
        //{
        //    string userName = this.Context.User.Identity.Name;
        //    string domainName = string.Empty;

        //    foreach (var item in dictionary)
        //    {
        //        if (domainName == string.Empty)
        //            domainName = item.Key.Split('@')[1];
        //        else if (domainName != item.Key.Split('@')[1])
        //            throw new Exception("All users must belong to this domain: " + domainName);
        //    }

        //    LiveEWS clEWS = GetLiveEWSClass(userName, domainName);
        //    List<LiveWebServiceBase.ReturnedTypes.MailMessage> result = new List<LiveWebServiceBase.ReturnedTypes.MailMessage> { };

        //    foreach (var item in dictionary)
        //    {
        //        result.Add(clEWS.GetMailMessage(item.Key, item.Value));
        //    }

        //    return result;
        //}
        #endregion

        #region Find Emails
        [WebMethod(Description = "Find Bulk Emails in Single Mailbox.", MessageName = "EWS_Email_Find1")]
        public LiveWebServiceBase.ReturnedTypes.UserMails EWS_Email_Find(string LiveID)
        {
            LiveEWS clEWS = new LiveEWS(suCurrentUser, LiveID);
            LiveWebServiceBase.ReturnedTypes.UserMails mails = new LiveWebServiceBase.ReturnedTypes.UserMails { };
            mails.mails = clEWS.MessageSearch(LiveID, new List<MailSearchParameter>(), new List<string>());
            mails.userLID = LiveID;

            return mails;
        }

        [WebMethod(Description = "Find Bulk Emails in Single Mailbox.", MessageName = "EWS_Email_Find2")]
        public LiveWebServiceBase.ReturnedTypes.UserMails EWS_Email_Find(string LiveID, WellKnownFolderName standardFolderName)
        {
            LiveEWS clEWS = new LiveEWS(suCurrentUser, LiveID);

            LiveWebServiceBase.ReturnedTypes.UserMails mails = new LiveWebServiceBase.ReturnedTypes.UserMails { };
            mails.mails = clEWS.MessageSearch(LiveID, standardFolderName);
            mails.userLID = LiveID;

            return mails;
        }

        [WebMethod(Description = "Find Bulk Emails in Single Mailbox.", MessageName = "EWS_Email_Find3")]
        public LiveWebServiceBase.ReturnedTypes.UserMails EWS_Email_Find(string LiveID, string folderName)
        {
            LiveEWS clEWS = new LiveEWS(suCurrentUser, LiveID);

            LiveWebServiceBase.ReturnedTypes.UserMails mails = new LiveWebServiceBase.ReturnedTypes.UserMails { };
            mails.mails = clEWS.MessageSearch(LiveID, new List<MailSearchParameter>(), new List<string>() { folderName });
            mails.userLID = LiveID;

            return mails;
        }

        [WebMethod(Description = "Find Bulk Emails in Single Mailbox.", MessageName = "EWS_Email_Find4")]
        public LiveWebServiceBase.ReturnedTypes.UserMails EWS_Email_Find(string LiveID, List<string> foldersNames)
        {
            LiveEWS clEWS = new LiveEWS(suCurrentUser, LiveID);

            LiveWebServiceBase.ReturnedTypes.UserMails mails = new LiveWebServiceBase.ReturnedTypes.UserMails { };
            mails.mails = clEWS.MessageSearch(LiveID, new List<MailSearchParameter>(), foldersNames);
            mails.userLID = LiveID;

            return mails;
        }

        [WebMethod(Description = "Find Bulk Emails in Single Mailbox.", MessageName = "EWS_Email_Find5")]
        public LiveWebServiceBase.ReturnedTypes.UserMails EWS_Email_Find(string LiveID, List<MailSearchParameter> parameters)
        {
            LiveEWS clEWS = new LiveEWS(suCurrentUser, LiveID);

            LiveWebServiceBase.ReturnedTypes.UserMails mails = new LiveWebServiceBase.ReturnedTypes.UserMails { };
            mails.mails = clEWS.MessageSearch(LiveID, parameters, new List<string>());
            mails.userLID = LiveID;

            return mails;
        }

        [WebMethod(Description = "Find Bulk Emails in Bulk Mailboxes", MessageName = "EWS_Email_Find6")]
        public List<LiveWebServiceBase.ReturnedTypes.UserMails> EWS_Email_Find(List<string> lstLiveIDs, List<MailSearchParameter> parameters)
        {
            if (lstLiveIDs.Distinct().Count() > 1)
            {
                throw new Exception("All users must belong to the same domain");
            }

            LiveEWS clEWS = new LiveEWS(suCurrentUser, lstLiveIDs.FirstOrDefault());

            return clEWS.GetMailsForMultipleUsers(lstLiveIDs, parameters);
        }

        [WebMethod(Description = "Find Bulk Emails in single Mailbox. Possible 'details' parameter values: '-1' include in message details message body; '0' do not include in message details message body; positive integer 'n' include in message details 'n' message body characters.")]
        public List<LiveWebServiceBase.ReturnedTypes.MailMessage> EWS_Email_Select(string LiveID, string folders, MessageSearchStatus status, int detalization, int resultsize, int offset)
        {
            LiveEWS clEWS = new LiveEWS(suCurrentUser, LiveID);

            return clEWS.MessageSearch(LiveID, folders, (int)status, detalization, resultsize, offset);
        }

        [WebMethod(Description = "Get current Exchange server host.")]
        public string EWS_Server_GetCurrent(string LiveID)
        {
            LiveEWS clEWS = new LiveEWS(suCurrentUser, LiveID);

            return clEWS.CurrnetServerUrl;
        }

        [WebMethod(Description = "Get url to existing Email message.")]
        public string EWS_Email_GetUrlById(string LiveID, string MailID, bool ReadOnly, bool IncludeSSO)
        {
            LiveEWS clEWS = new LiveEWS(suCurrentUser, LiveID);
            string mailUrl = clEWS.GetMailUrlById(LiveID, MailID, ReadOnly);

            return (IncludeSSO) ? SSO_GetUrl(LiveID, mailUrl) : mailUrl;
        }
        #endregion

        #region Create Email
        [WebMethod(Description = "Create and send new Email message.", MessageName = "EWS_Email_Create1")]
        public void EWS_Email_Create(string senderLiveID, string subject, string body, string sendto)
        {
            EWS_Email_Create(senderLiveID, subject, body, new List<string> { sendto }, new List<LiveWebServiceBase.ReturnedTypes.MailAttachment>());
        }

        [WebMethod(Description = "Create and send new Email message with attachments.", MessageName = "EWS_Email_Create2")]
        public void EWS_Email_Create(string senderLiveID, string subject, string body, string sendto, List<LiveWebServiceBase.ReturnedTypes.MailAttachment> attachments)
        {
            EWS_Email_Create(senderLiveID, subject, body, new List<string> { sendto }, attachments);
        }

        [WebMethod(Description = "Create and send new Email message.", MessageName = "EWS_Email_Create3")]
        public void EWS_Email_Create(string senderLiveID, string subject, string body, List<string> sendto)
        {
            EWS_Email_Create(senderLiveID, subject, body, sendto, new List<LiveWebServiceBase.ReturnedTypes.MailAttachment>());
        }

        [WebMethod(Description = "Create and send new Email message with attachments.", MessageName = "EWS_Email_Create4")]
        public void EWS_Email_Create(string senderLiveID, string subject, string body, List<string> sendto, List<LiveWebServiceBase.ReturnedTypes.MailAttachment> attachments)
        {
            LiveEWS clEWS = new LiveEWS(suCurrentUser, senderLiveID);

            clEWS.CreateAndSendMessage(senderLiveID, subject, body, sendto, attachments);
        }

        [WebMethod(Description = "Create new Email message in draft folder and return message ulr.")]
        public string EWS_Email_CreateDraftMessage(string senderLiveID, string subject, string body, List<string> sendto, bool IncludeSSO)
        {
            LiveEWS clEWS = new LiveEWS(suCurrentUser, senderLiveID);
            string DraftMessageUrl = clEWS.CreateDraftMessage(senderLiveID, subject, body, sendto);

            return (IncludeSSO) ? SSO_GetUrl(senderLiveID, DraftMessageUrl) : DraftMessageUrl;
        }
        #endregion

        #region Delete Email
        [WebMethod(Description = "Delete single Email messages using Mail ID.", MessageName = "EWS_Email_Delete1")]
        public void EWS_Email_Delete(string LiveID, string MailID, bool hardDelete)
        {
            LiveEWS clEWS = new LiveEWS(suCurrentUser, LiveID);

            clEWS.DeleteMessage(LiveID, MailID, hardDelete);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dictionary">Key is LiveID and Value is MailID</param>
        /// <param name="hardDelete"></param>
        //[WebMethod(Description = "Delete single/Bulk Email messages using Mail ID/IDs.", MessageName = "EWS_Email_Delete12")]
        //public void EWS_Email_Delete(Dictionary<string, string> dictionary, bool hardDelete)
        //{
        //    string userName = this.Context.User.Identity.Name;
        //    string domainName = string.Empty;

        //    foreach (var item in dictionary)
        //    {
        //        if (domainName == string.Empty)
        //            domainName = item.Key.Split('@')[1];
        //        else if (domainName != item.Key.Split('@')[1])
        //            throw new Exception("All users must belong to this domain: " + domainName);
        //    }

        //    LiveEWS clEWS = GetLiveEWSClass(userName, domainName);

        //    foreach (var item in dictionary)
        //    {
        //        clEWS.DeleteMessage(item.Key, item.Value, hardDelete);
        //    }
        //}
        #endregion

        #region Create Appointment
        [WebMethod(Description = "Create new single appointment for single Mailbox.", MessageName = "EWS_Appointment_Create1")]
        public void EWS_Appointment_Create(string LiveID, string subject, string body, string location, DateTime startDate, DateTime endDate)
        {
            LiveEWS clEWS = new LiveEWS(suCurrentUser, LiveID);

            clEWS.CreateAppointment(LiveID, subject, body, location, startDate, endDate);
        }

        [WebMethod(Description = "Create new single appointment for bulk Mailboxes.", MessageName = "EWS_Appointment_Create2")]
        public void EWS_Appointment_Create(List<string> lstLiveIDs, string subject, string body, string location, DateTime startDate, DateTime endDate)
        {
            if (lstLiveIDs.Select(le => le.Split('@')[1]).Distinct().Count() > 1)
            {
                throw new Exception("All users must belong to the same domain");
            }

            LiveEWS clEWS = new LiveEWS(suCurrentUser, lstLiveIDs.FirstOrDefault());

            foreach (string item in lstLiveIDs)
            {
                clEWS.CreateAppointment(item, subject, body, location, startDate, endDate);
            }
        }

        [WebMethod(Description = "Create new appointment and return ulr.")]
        public string EWS_Appointment_Open(string senderLiveID, string subject, string body, string location, DateTime startDate, DateTime endDate)
        {
            LiveEWS clEWS = new LiveEWS(suCurrentUser, senderLiveID);

            return clEWS.CreateDraftAppointment(senderLiveID, subject, body, location, startDate, endDate);
        }
        #endregion

        #region Delete Appointment
        [WebMethod(Description = "Delete single appointment for single Mailbox.", MessageName = "EWS_Appointment_Delete1")]
        public void EWS_Appointment_Delete(string LiveID, string appointmentID, bool hardDelete)
        {
            LiveEWS clEWS = new LiveEWS(suCurrentUser, LiveID);

            clEWS.DeleteAppointment(LiveID, appointmentID, hardDelete);
        }

        [WebMethod(Description = "Delete single appointment for bulk Mailbox.", MessageName = "EWS_Appointment_Delete2")]
        public void EWS_Appointment_Delete(List<string> lstLiveIDs, string appointmentID, bool hardDelete)
        {
            if (lstLiveIDs.Distinct().Count() > 1)
            {
                throw new Exception("All users must belong to the same domain");
            }

            LiveEWS clEWS = new LiveEWS(suCurrentUser, lstLiveIDs.FirstOrDefault());

            foreach (string item in lstLiveIDs)
            {
                clEWS.DeleteAppointment(item, appointmentID, hardDelete);
            }
        }
        #endregion

        #region Find Appointment
        [WebMethod(Description = "Get single appointment using Appointment ID", MessageName = "EWS_Appointment_Find1")]
        public LiveWebServiceBase.ReturnedTypes.Appointment EWS_Appointment_Find(string LiveID, string appointmentID)
        {
            LiveEWS clEWS = new LiveEWS(suCurrentUser, LiveID);

            return clEWS.GetAppointmentContent(LiveID, appointmentID);
        }

        //appointment parameters, string parameter
        [WebMethod(Description = "Get bulk appointments using interval between start date and end date.", MessageName = "EWS_Appointment_Find2")]
        public List<LiveWebServiceBase.ReturnedTypes.Appointment> EWS_Appointment_Find(string LiveID, DateTime startDate, DateTime endDate)
        {
            LiveEWS clEWS = new LiveEWS(suCurrentUser, LiveID);

            return clEWS.GetAppointments(LiveID, startDate, endDate, string.Empty);
        }

        [WebMethod(Description = "Get bulk appointments using interval between start date and end date.")]
        public List<LiveWebServiceBase.ReturnedTypes.Appointment> EWS_Appointment_Select(string LiveID, DateTime startDate, DateTime endDate)
        {
            return EWS_Appointment_Find(LiveID, startDate, endDate);
        }

        [WebMethod(Description = "Get bulk appointments using interval between start date and end date.", MessageName = "EWS_Appointment_Select2")]
        public List<LiveWebServiceBase.ReturnedTypes.Appointment> EWS_Appointment_Select(string LiveID, DateTime startDate, DateTime endDate, string calendarName)
        {
            LiveEWS clEWS = new LiveEWS(suCurrentUser, LiveID);

            return clEWS.GetAppointments(LiveID, startDate, endDate, calendarName);
        }

        [WebMethod(Description = "Get url to existing appointment.")]
        public string EWS_Appointment_GetUrlById(string LiveID, string AppointmentID, bool ReadOnly, bool IncludeSSO)
        {
            LiveEWS clEWS = new LiveEWS(suCurrentUser, LiveID);
            string mailUrl = clEWS.GetAppointmentUrlById(LiveID, AppointmentID, ReadOnly);

            return (IncludeSSO) ? SSO_GetUrl(LiveID, mailUrl) : mailUrl;
        }

        #endregion

        #region Create Contact
        [WebMethod(Description = "Create single contact.")]
        public void EWS_Contact_Create(string LiveID, System.Web.UI.Pair[] parameters)
        {
            Dictionary<ContactParameterType, object> dict = new Dictionary<ContactParameterType, object>();

            foreach (var item in parameters)
            {
                dict.Add((ContactParameterType)item.First, item.Second);
            }

            LiveEWS clEWS = new LiveEWS(suCurrentUser, LiveID);

            clEWS.CreateContact(LiveID, dict);
        }
        #endregion

        #region Update Contact
        [WebMethod(Description = "Update single contact.")]
        public void EWS_Contact_Update(string LiveID, string ContactID, System.Web.UI.Pair[] parameters)
        {
            Dictionary<ContactParameterType, object> dict = new Dictionary<ContactParameterType, object>();

            foreach (var item in parameters)
            {
                dict.Add((ContactParameterType)item.First, item.Second);
            }

            LiveEWS clEWS = new LiveEWS(suCurrentUser, LiveID);
            clEWS.EditContact(LiveID, ContactID, dict);
        }
        #endregion

        #region Delete Contact
        [WebMethod(Description = "Delete single contact.")]
        public void EWS_Contact_Delete(string LiveID, string ContactID)
        {
            LiveEWS clEWS = new LiveEWS(suCurrentUser, LiveID);
            clEWS.DeleteContact(LiveID, ContactID);
        }
        #endregion

        #region Get Contact
        [WebMethod(Description = "Get single contact.", MessageName = "EWS_Contact_Get1")]
        public LiveWebServiceBase.ReturnedTypes.Contact EWS_Contact_Get(string LiveID, string ContactID)
        {
            LiveEWS clEWS = new LiveEWS(suCurrentUser, LiveID);
            return clEWS.GetContact(LiveID, ContactID);
        }

        [WebMethod(Description = "Get bulk contacts.", MessageName = "EWS_Contact_Get2")]
        public LiveWebServiceBase.ReturnedTypes.Contact[] EWS_Contact_Get(string LiveID, WellKnownFolderName FolderName, System.Web.UI.Pair[] parameters)
        {
            Dictionary<ContactParameterType, object> dict = new Dictionary<ContactParameterType, object>();

            foreach (var item in parameters)
                dict.Add((ContactParameterType)item.First, item.Second);

            LiveEWS clEWS = new LiveEWS(suCurrentUser, LiveID);
            return clEWS.GetContact(LiveID, FolderName, dict);
        }

        [WebMethod(Description = "Get bulk contacts.", MessageName = "EWS_Contact_Get3")]
        public LiveWebServiceBase.ReturnedTypes.Contact[] EWS_Contact_Get(string LiveID, string FolderId, System.Web.UI.Pair[] parameters)
        {
            Dictionary<ContactParameterType, object> dict = new Dictionary<ContactParameterType, object>();

            foreach (var item in parameters)
                dict.Add((ContactParameterType)item.First, item.Second);

            LiveEWS clEWS = new LiveEWS(suCurrentUser, LiveID);
            return clEWS.GetContact(LiveID, FolderId, dict);
        }

        [WebMethod(Description = "Get bulk contacts.", MessageName = "EWS_Contact_Get4")]
        public LiveWebServiceBase.ReturnedTypes.Contact[] EWS_Contact_Get(string LiveID, System.Web.UI.Pair[] parameters)
        {
            return EWS_Contact_Get(LiveID, WellKnownFolderName.Contacts, parameters);
        }
        #endregion

        #region Create Folder
        [WebMethod(Description = "Create single folder.", MessageName = "EWS_Folder_Create1")]
        public void EWS_Folder_Create(string LiveID, string parentFolderID, System.Web.UI.Pair[] parameters)
        {
            Dictionary<FolderParameterType, object> dict = new Dictionary<FolderParameterType, object>();

            foreach (var item in parameters)
            {
                dict.Add((FolderParameterType)item.First, item.Second);
            }

            LiveEWS clEWS = new LiveEWS(suCurrentUser, LiveID);
            clEWS.CreateFolder(LiveID, parentFolderID, dict);
        }

        [WebMethod(Description = "Create single folder.", MessageName = "EWS_Folder_Create2")]
        public void EWS_Folder_Create(string LiveID, WellKnownFolderName parentFolderType, System.Web.UI.Pair[] parameters)
        {
            Dictionary<FolderParameterType, object> dict = new Dictionary<FolderParameterType, object>();

            foreach (var item in parameters)
            {
                dict.Add((FolderParameterType)item.First, item.Second);
            }

            LiveEWS clEWS = new LiveEWS(suCurrentUser, LiveID);
            clEWS.CreateFolder(LiveID, parentFolderType, dict);
        }
        #endregion

        #region Delete Folder
        [WebMethod(Description = "Delete single contact.")]
        public void EWS_Folder_Delete(string LiveID, string FolderID)
        {
            LiveEWS clEWS = new LiveEWS(suCurrentUser, LiveID);
            clEWS.DeleteFolder(LiveID, FolderID);
        }
        #endregion

        #region Update Folder
        [WebMethod(Description = "Update single folder.")]
        public void EWS_Folder_Update(string LiveID, string FolderID, System.Web.UI.Pair[] parameters)
        {
            Dictionary<FolderParameterType, object> dict = new Dictionary<FolderParameterType, object>();

            foreach (var item in parameters)
            {
                dict.Add((FolderParameterType)item.First, item.Second);
            }

            LiveEWS clEWS = new LiveEWS(suCurrentUser, LiveID);
            clEWS.UpdateFolder(LiveID, FolderID, dict);
        }
        #endregion

        #region Get Folder
        [WebMethod(Description = "Get single folder.", MessageName = "EWS_Folder_Get1")]
        public LiveWebServiceBase.ReturnedTypes.Folder EWS_Folder_Get(string LiveID, string FolderID)
        {
            LiveEWS clEWS = new LiveEWS(suCurrentUser, LiveID);
            return clEWS.GetFolder(LiveID, FolderID);
        }

        [WebMethod(Description = "Get bulk folders.", MessageName = "EWS_Folder_Get2")]
        public LiveWebServiceBase.ReturnedTypes.Folder[] EWS_Folder_Get(string LiveID, WellKnownFolderName FolderType, System.Web.UI.Pair[] parameters)
        {
            Dictionary<FolderSearchParameterType, object> dict = new Dictionary<FolderSearchParameterType, object>();

            foreach (var item in parameters)
                dict.Add((FolderSearchParameterType)item.First, item.Second);

            LiveEWS clEWS = new LiveEWS(suCurrentUser, LiveID);
            return clEWS.GetFolder(LiveID, FolderType, dict);
        }

        [WebMethod(Description = "Get bulk folders.", MessageName = "EWS_Folder_Get3")]
        public LiveWebServiceBase.ReturnedTypes.Folder[] EWS_Folder_Get(string LiveID, string parentFolderID, System.Web.UI.Pair[] parameters)
        {
            Dictionary<FolderSearchParameterType, object> dict = new Dictionary<FolderSearchParameterType, object>();

            foreach (var item in parameters)
                dict.Add((FolderSearchParameterType)item.First, item.Second);

            LiveEWS clEWS = new LiveEWS(suCurrentUser, LiveID);
            return clEWS.GetFolder(LiveID, parentFolderID, dict);
        }

        [WebMethod(Description = "Get bulk folders.", MessageName = "EWS_Folder_Get4")]
        public LiveWebServiceBase.ReturnedTypes.Folder[] EWS_Folder_Get(string LiveID, System.Web.UI.Pair[] parameters)
        {
            Dictionary<FolderSearchParameterType, object> dict = new Dictionary<FolderSearchParameterType, object>();

            foreach (var item in parameters)
                dict.Add((FolderSearchParameterType)item.First, item.Second);

            LiveEWS clEWS = new LiveEWS(suCurrentUser, LiveID);
            return clEWS.GetFolder(LiveID, dict);
        }
        #endregion

        #region Find Folder
        [WebMethod(Description = "Find folders by display name.", MessageName = "EWS_Folder_Find1")]
        public LiveWebServiceBase.ReturnedTypes.Folder[] EWS_Folder_Find(string LiveID, string folderName)
        {
            LiveEWS clEWS = new LiveEWS(suCurrentUser, LiveID);
            return clEWS.FindFolder(LiveID, folderName);
        }
        #endregion

        #endregion

        #region PowerShellWraper
        #region Create session
        //[WebMethod(Description = "Create new PowerShell Session. You don't need to use this method, because PSSession is automatically created upon any PS-method call.", MessageName = "PS_Session_New1")]
        //public void PS_Session_New(string sessionName)
        //{
        //    PS_Session_New(sessionName, null);
        //}

        //[WebMethod(Description = "Create new PowerShell Session. You don't need to use this method, because PSSession is automatically created upon any PS-method call.", MessageName = "PS_Session_New2")]
        //public void PS_Session_New(string sessionName, String domainName)
        //{
        //    if (domainName == null)
        //    {
        //        List<string> domains = suCurrentUser.GetDomains();

        //        if (domains.Count == 1)
        //            domainName = domains[0];
        //        else
        //        {
        //            throw new Exception("You have more than one domain. You should set domain property.");
        //        }
        //    }

        //    LivePSW clLivePS = GetLivePSWClass(userName, domainName, sessionName);

        //    objPS PSobj = new objPS();
        //    PSobj.userName = userName;
        //    PSobj.sessionName = sessionName;
        //    PSobj.initTime = DateTime.Now;
        //    PSobj.clLivePSW = clLivePS;

        //    lstPSSessions.Add(PSobj);
        //}
        #endregion

        #region Get session name
        //[WebMethod(Description = "Gets current PowerShell Session name.")]
        //public string PS_Session_GetName()
        //{
        //    objPS session = lstPSSessions.SingleOrDefault(le => le.userName == this.Context.User.Identity.Name);
        //    if (session != null && session.clLivePSW != null)
        //    {
        //        if (session.initTime.AddMinutes(12) <= DateTime.Now)
        //        {
        //            session.clLivePSW.CloseSession();
        //            lstPSSessions.Remove(session);
        //            throw new Exception("Current session closed by timeout.");
        //        }

        //        return session.sessionName;
        //    }
        //    else return "Can't find active session.";
        //}
        #endregion

        #region Close session
        [WebMethod(Description = "Close current PowerShell Session.")]
        public void PS_Session_Close()
        {
            //if (lstPSSessions.Count(le => le.userName == this.Context.User.Identity.Name) != 1)
            //    throw new Exception("Didn't have active session.");
            //else
            //{
            //    objPS session = lstPSSessions.Single(le => le.userName == this.Context.User.Identity.Name);

            //    session.clLivePSW.CloseSession();
            //    session.clLivePSW = null;
            //    lstPSSessions.Remove(session);
            //}
        }
        #endregion

        #region Create Mailbox
        [WebMethod(Description = "Create single Mailbox or user account for Office 365.")]
        public void PS_Mailbox_Create(string LiveID, string emailAddress, int forceChangePassword, string password, string displayName, string firstName, string lastName)
        {
            LivePSW lvPSW = new LivePSW(suCurrentUser, LiveID);
            lvPSW.CreateNewMailbox(LiveID, emailAddress, forceChangePassword, password, displayName, firstName, lastName);
        }
        #endregion

        #region Assigng Licenses
        [WebMethod(Description = "Assigin licences to user account for Office 365.")]
        public void PS_Assign_Licenses(string UserPrincipalName, string usagelocation, string licenses)
        {
            LivePSW lvPSW = new LivePSW(suCurrentUser, UserPrincipalName);
            lvPSW.AssignLicenses(UserPrincipalName, usagelocation, licenses);
        }
        #endregion

        #region Set Mailbox
        [WebMethod(Description = "Set parameters for single mailbox.", MessageName = "PS_Mailbox_Set1")]
        public void PS_Mailbox_Set(string emailAddress, string parameters)
        {
            LivePSW lvPSW = new LivePSW(suCurrentUser, emailAddress);
            lvPSW.SetMailboxParameters(emailAddress, parameters);
        }

        [WebMethod(Description = "Set parameters for single mailbox.", MessageName = "PS_Mailbox_Set2")]
        public void PS_Mailbox_Set(List<string> emailAddress, string parameters)
        {
            if (emailAddress.Distinct().Count() > 1)
            {
                throw new Exception("All users must belong to the same domain");
            }

            LivePSW lvPSW = new LivePSW(suCurrentUser, emailAddress.FirstOrDefault());

            foreach (string item in emailAddress)
            {
                lvPSW.SetMailboxParameters(item, parameters);
            }
        }
        #endregion

        #region Create Distribution Group
        [WebMethod(Description = "Create single Distribution Group.", MessageName = "PS_Group_Create1")]
        public void PS_Group_Create(string name)
        {
            PS_Group_Create(name, null);
        }

        [WebMethod(Description = "Create bulk Distribution Groups.", MessageName = "PS_Group_Create2")]
        public void PS_Group_Create(List<string> name)
        {
            foreach (string item in name)
                PS_Group_Create(item, null);
        }

        [WebMethod(Description = "Create single Distribution Group.", MessageName = "PS_Group_Create3")]
        public void PS_Group_Create(string name, String domain)
        {
            if (domain == null)
            {
                List<string> domains = suCurrentUser.GetDomains();

                if (domains.Count == 1)
                    domain = domains[0];
                else
                {
                    throw new Exception("You have more than one domain. You should set domain property.");
                }
            }

            LivePSW lvPSW = new LivePSW(suCurrentUser, "admin@" + domain);
            lvPSW.CreateNewGroup(name);
        }

        [WebMethod(Description = "Create bulk Distribution Groups.", MessageName = "PS_Group_Create4")]
        public void PS_Group_Create(List<string> name, String domain)
        {
            if (domain == null)
            {
                List<string> domains = suCurrentUser.GetDomains();

                if (domains.Count == 1)
                    domain = domains[0];
                else
                {
                    throw new Exception("You have more than one domain. You should set domain property.");
                }
            }

            LivePSW lvPSW = new LivePSW(suCurrentUser, "admin@" + domain);

            foreach (string item in name)
                lvPSW.CreateNewGroup(item);
        }
        #endregion

        #region Set Distribution Group
        [WebMethod(Description = "Set parameters for single Distribution Group.", MessageName = "PS_Group_Set1")]
        public void PS_Group_Set(string name, string parameters)
        {
            PS_Group_Set(name, null, parameters);
        }

        [WebMethod(Description = "Set parameters for single Distribution Group.", MessageName = "PS_Group_Set2")]
        public void PS_Group_Set(string name, string parameters, String domain)
        {
            if (domain == null)
            {
                List<string> domains = suCurrentUser.GetDomains();

                if (domains.Count == 1)
                    domain = domains[0];
                else
                {
                    throw new Exception("You have more than one domain. You should set domain property.");
                }
            }

            LivePSW lvPSW = new LivePSW(suCurrentUser, "admin@" + domain);
            lvPSW.SetGroupParameters(name, parameters);
        }
        #endregion

        #region Add member to Distribution Group
        [WebMethod(Description = "Add single Member to Distribution Group.", MessageName = "PS_Group_AddMember1")]
        public void PS_Group_AddMember(string groupName, string emailAddress)
        {
            LivePSW lvPSW = new LivePSW(suCurrentUser, emailAddress);
            lvPSW.AddMemberToGroup(groupName, emailAddress);
        }

        [WebMethod(Description = "Add bulk Member to Distribution Group.", MessageName = "PS_Group_AddMember2")]
        public void PS_Group_AddMember(string groupName, List<string> emailAddress)
        {
            if (emailAddress.Distinct().Count() > 1)
            {
                throw new Exception("All users must belong to the same domain");
            }

            LivePSW lvPSW = new LivePSW(suCurrentUser, emailAddress.FirstOrDefault());

            foreach (string item in emailAddress)
                lvPSW.AddMemberToGroup(groupName, item);
        }
        #endregion

        #region Create Dynamic Distribution Group
        [WebMethod(Description = "Create single Dynamic Distribution Group.", MessageName = "PS_DGroup_Create1")]
        public void PS_DGroup_Create(string groupName, string parameters, string recipients)
        {
            PS_DGroup_Create(groupName, parameters, recipients, null);
        }

        [WebMethod(Description = "Create single Dynamic Distribution Group.", MessageName = "PS_DGroup_Create2")]
        public void PS_DGroup_Create(string groupName, string parameters, string recipients, String domain)
        {
            if (domain == null)
            {
                List<string> domains = suCurrentUser.GetDomains();

                if (domains.Count == 1)
                    domain = domains[0];
                else
                {
                    throw new Exception("You have more than one domain. You should set domain property.");
                }
            }

            LivePSW lvPSW = new LivePSW(suCurrentUser, "admin@" + domain);
            lvPSW.CreateDynamicGroup(groupName, recipients, parameters);
        }
        #endregion

        #region Set Dynamic Distribution Group
        [WebMethod(Description = "Set parameters for single Dynamic Distribution Group.", MessageName = "PS_DGroup_Set1")]
        public void PS_DGroup_Set(string groupName, string parameters)
        {
            PS_DGroup_Set(groupName, parameters, null);
        }

        [WebMethod(Description = "Set parameters for single Dynamic Distribution Groups.", MessageName = "PS_DGroup_Set2")]
        public void PS_DGroup_Set(string groupName, string parameters, String domain)
        {
            if (domain == null)
            {
                List<string> domains = suCurrentUser.GetDomains();

                if (domains.Count == 1)
                    domain = domains[0];
                else
                {
                    throw new Exception("You have more than one domain. You should set domain property.");
                }
            }

            LivePSW lvPSW = new LivePSW(suCurrentUser, "admin@" + domain);
            lvPSW.SetDynamicGroupParameters(groupName, parameters);
        }
        #endregion

        #region Add new Mailboxes to LiveID
        /// <summary>
        /// Add new mailboxes for single LiveID
        /// </summary>
        /// <param name="LiveID">User Windows Live ID</param>
        /// <param name="emails">New user email addresses devided by ',' or single email address</param>
        /// <param name="useExisting">Add new email addresses to existing or replace and make first mail adress as primary</param>
        [WebMethod(Description = "Add new mailboxes for single LiveID.")]
        public void PS_Mailbox_AddAlias(string LiveID, string emails, bool useExisting)
        {
            Regex exp = new Regex(@"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");

            string emailsParam = string.Empty;

            foreach (string email in emails.Split(','))
            {
                if (exp.IsMatch(email.Trim()))
                    emailsParam += email.Trim() + "','";
            }

            emailsParam = emailsParam.Remove(emailsParam.Length - 3);

            LivePSW lvPSW = new LivePSW(suCurrentUser, LiveID);
            lvPSW.SetMailboxAlias(LiveID, emailsParam, useExisting);
        }
        #endregion

        #region Remove Mailboxes from LiveID
        /// <summary>
        /// Remove existing mailboxes from single LiveID
        /// </summary>
        /// <param name="LiveID">User Windows Live ID</param>
        /// <param name="emails">User email addresses for remove devided by ',' or single email address</param>
        [WebMethod(Description = "Remove existing mailboxes from single LiveID.")]
        public void PS_Mailbox_RemoveAlias(string LiveID, string emails)
        {
            Regex exp = new Regex(@"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");

            string emailsParam = string.Empty;

            foreach (string email in emails.Split(','))
            {
                if (exp.IsMatch(email.Trim()))
                    emailsParam += email.Trim() + "','";
            }

            emailsParam = emailsParam.Remove(emailsParam.Length - 3);

            LivePSW lvPSW = new LivePSW(suCurrentUser, LiveID);
            lvPSW.RemoveMailboxAlias(LiveID, emailsParam);
        }
        #endregion

        #region Reset LiveID password
        [WebMethod(Description = "Reset password for single LiveID.")]
        public void PS_Mailbox_ResetPassword(string LiveID, string password, bool forceChangePassword)
        {
            LivePSW lvPSW = new LivePSW(suCurrentUser, LiveID);
            lvPSW.ResetPassword(LiveID, password, forceChangePassword);
        }
        #endregion

        #region Execute command
        [WebMethod(Description = "Execute single PowerShell command.", MessageName = "PS_Execute1")]
        public List<PSResult> PS_Execute(string command)
        {
            return PS_Execute(command, null);
        }

        [WebMethod(Description = "Execute bulk PowerShell commands.", MessageName = "PS_Execute2")]
        public List<PSResult> PS_Execute(List<string> commands)
        {
            return PS_Execute(commands, null);
        }

        [WebMethod(Description = "Execute single PowerShell command.", MessageName = "PS_Execute3")]
        public List<PSResult> PS_Execute(string command, String domain)
        {
            if (domain == null)
            {
                List<string> domains = suCurrentUser.GetDomains();

                if (domains.Count == 1)
                    domain = domains[0];
                else
                {
                    throw new Exception("You have more than one domain. You should set domain property.");
                }
            }

            LivePSW lvPSW = new LivePSW(suCurrentUser, "admin@" + domain);
            return lvPSW.ExecutePowerShellCommand(command);
        }

        [WebMethod(Description = "Execute bulk PowerShell commands.", MessageName = "PS_Execute4")]
        public List<PSResult> PS_Execute(List<string> commands, String domain)
        {
            if (domain == null)
            {
                List<string> domains = suCurrentUser.GetDomains();

                if (domains.Count == 1)
                    domain = domains[0];
                else
                {
                    throw new Exception("You have more than one domain. You should set domain property.");
                }
            }

            LivePSW lvPSW = new LivePSW(suCurrentUser, "admin@" + domain);
            return lvPSW.ExecutePowerShellCommand(commands);
        }

        [WebMethod(Description = "Execute single PowerShell command.", MessageName = "PS_ExecuteByDomain")]
        public List<PSResult> PS_ExecuteByDomain(string command, String domain)
        {
            return PS_Execute(command, domain);
        }
        #endregion

        #endregion

        #region Other functions

        [WebMethod(Description = "Enumerate domains for current user configfile.")]
        public string[] EFMS_GetMyPrimaryDomains()
        {
            return suCurrentUser.GetDomains().ToArray();
        }

        #endregion

        #region Private functions
        //private LivePSW GetLivePSWClass(string userName, string domainName)
        //{
        //    return GetLivePSWClass(userName, domainName, null);
        //}

        //private LivePSW GetLivePSWClass(string userName, string domainName, String SessionName)
        //{
        //    string ItemKey = userName + domainName;
        //    string _sessionName;

        //    if (SessionName == null)
        //        _sessionName = userName.Split('\\')[1] + "_session";
        //    else
        //        _sessionName = SessionName;

        //    LivePSW tmpPSW = null;

        //    if (lstPSSessions.Count(le => le.userName == ItemKey && le.sessionName == _sessionName) > 1)
        //    {
        //        var sessions = lstPSSessions.Where(le => le.userName == ItemKey && le.sessionName == _sessionName);

        //        foreach (var item in sessions)
        //        {
        //            try
        //            {
        //                item.clLivePSW.CloseSession();
        //                item.clLivePSW = null;
        //            }
        //            catch { }
        //        }

        //        lstPSSessions.RemoveAll(le => le.userName == ItemKey);
        //    }

        //    if (lstPSSessions.Count(le => le.userName == ItemKey && le.sessionName == _sessionName) == 0)
        //    {
        //        LiveClasses clLive = new LiveClasses();
        //        tmpPSW = clLive.GetLivePSW(userName, domainName, _sessionName);

        //        objPS pswItemNew = new objPS();
        //        pswItemNew.initTime = DateTime.Now;
        //        pswItemNew.userName = ItemKey;
        //        pswItemNew.sessionName = _sessionName;
        //        pswItemNew.clLivePSW = tmpPSW;

        //        lstPSSessions.Add(pswItemNew);
        //    }
        //    else
        //    {
        //        objPS pswItemOld = lstPSSessions.Single(le => le.userName == ItemKey && le.sessionName == _sessionName);
        //        tmpPSW = pswItemOld.clLivePSW;

        //        //if (pswItemOld.initTime.AddMinutes(PSLifeTime) > DateTime.Now)
        //        //{
        //        //    tmpPSW = pswItemOld.clLivePSW;
        //        //    pswItemOld.initTime = DateTime.Now;
        //        //}
        //        //else
        //        //{
        //        //    try
        //        //    {
        //        //        pswItemOld.clLivePSW.CloseSession();
        //        //        pswItemOld.clLivePSW = null;
        //        //    }
        //        //    catch { }

        //        //    lstPSSessions.Remove(pswItemOld);

        //        //    LiveClasses clLive = new LiveClasses();
        //        //    tmpPSW = clLive.GetLivePSW(userName, domainName, _sessionName);

        //        //    objPS pswItemNew = new objPS();
        //        //    pswItemNew.initTime = DateTime.Now;
        //        //    pswItemNew.userName = userName;
        //        //    pswItemNew.sessionName = _sessionName;
        //        //    pswItemNew.clLivePSW = tmpPSW;

        //        //    lstPSSessions.Add(pswItemNew);
        //        //}
        //    }

        //    return tmpPSW;
        //}
        #endregion
    }
}
